from soj.settings.compile.cpp import *
from soj.settings.compile.common import MAX_COMPILE_TIME
from soj.builtin.environ.workspace import WorkSpace
from soj.builtin.compile.common import ensure_file,CompileResult,translate_msg
from pathlib import Path
import subprocess as sp
import platform
if platform.system()=="Windows":
    OUTPUT_FILE="foo.exe"
else:
    OUTPUT_FILE="foo"
class CppCompile:
    def __init__(self,source:Path,std:str,with_o2:bool=False):
        ensure_file(source)
        self.source=source
        self.args=CPP_ARG+' '+(CPP_O0 if not with_o2 else CPP_O2)+' '+CPP_STD[std]
    def compile(self)->CompileResult:
        ensure_file(self.source)
        ws=WorkSpace(create_files=False)
        ws.import_file(ws.FileType.CUSTOM,self.source,rename="source.cpp")
        file=ws.join_path(OUTPUT_FILE)
        ok=True
        try:
            # import os
            # print("IS W"+str(os.access(ws.dir.name,os.W_OK)))
            # print("IS R"+str(os.access(ws.dir.name,os.R_OK)))
            # print("IS X"+str(os.access(ws.dir.name,os.X_OK)))
            # os.system(f"{GXX_PATH} -o {file} {ws.join("source.cpp")}")
            # args_list=[GXX_PATH]+[f"-o {file}",f"{ws.join("source.cpp")}"]
            args_list=[GXX_PATH]+self.args.split(' ')+['-o',str(file),ws.join("source.cpp")]
            result=sp.run(args_list,cwd=ws.dir.name,shell=True,
                        timeout=MAX_COMPILE_TIME,capture_output=True,text=True)
        except Exception as e:
            ok=False
            print(f"Compile CPP: Error {e}")
        try:
            ensure_file(file)
        except Exception as e:
            ok=False
        if result.returncode!=0:
            ok=False
        return {
            'ok':ok,
            'artifact':file,
            'msg':translate_msg(result.stderr),
            'output':ws
        }

class Cpp14O2(CppCompile):
    def __init__(self, source):
        super().__init__(source, "c++14", True)

class Cpp14(CppCompile):
    def __init__(self, source):
        super().__init__(source, "c++14", False)

class Cpp17O2(CppCompile):
    def __init__(self, source):
        super().__init__(source, "c++17", True)